#include "GameLayer.h"
#include "StaticData.h"
#include "Auger.h"
#include "Brush.h"
#include "cocos-ext.h"
#include <functional>

using namespace extension;

GameLayer::GameLayer(void){
    testnum = 0;
	op = 255;
    fixSpeed = 25;
    mins = 2;
    secs = 59;
}

GameLayer::~GameLayer(void){
    CC_SAFE_RELEASE_NULL(_augerTooth);
     CC_SAFE_RELEASE_NULL(_brushTooth);
     CC_SAFE_RELEASE_NULL(_fixTooth);
     CC_SAFE_RELEASE_NULL(_hookTooth);
     CC_SAFE_RELEASE_NULL(_pliersTooth);
     CC_SAFE_RELEASE_NULL(_polishTooth);
}

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, elems);
    return elems;
}

int GameLayer::randint(int l,int u){
    int temp = floor(l+(1.0*rand()/RAND_MAX)*(u-l+1));
    return temp;
}

std::set<int> GameLayer::gen(int n, int m){
    int i = 0;
    std::set<int> rs;
    while(i < m){
        int r = randint(1,n);
        if (rs.count(r)==0){
            rs.insert(r);
            i += 1;
        }
    }
    return rs;
}

void print(int x){
    CCLOG("random: %i",x);
}

void GameLayer::addBadTooth(int x) {

    std::string test = "abcde";
    int r = 0;
    bool b = true;
    if((badToothA.count(x) + badToothB.count(x)) >1){
        test = "abce";
        r = randint(0,3);
        b = true;
    }else{
        test = "abcde";
        r = randint(0,4);
        b = false;
    }

    std::ostringstream s;
    s << test[r] << x;
    CCLOG("type %i, %lu, %c",x,(badToothA.count(x) + badToothB.count(x)),test[r]);
    if(checkSet){
        bool jump = true;
        while(jump){
            if(badToothC.count(s.str())==0){
                jump = false;
                badToothC.insert(s.str());
            }else{
                if(b){
                  r = randint(0,3);
                }else{
                  r = randint(0,4);
                }
                s.clear();
                s.str("");
                s << test[r] << x;
            }
        }
    }else{
        badToothC.insert(s.str());
    }
}

bool GameLayer::init()
{    
    bool pRet = false;
    
    do {
        CC_BREAK_IF(!CCLayer::init());
        std::string level = CCUserDefault::sharedUserDefault()->getStringForKey("level");
        CCLOG("random4: %s",level.c_str());
        std::vector<std::string> levelInfo = split(level, '-');
        bigLevel = &levelInfo.at(0);
        littleLevel = &levelInfo.at(1);
     
        labelAtlas = CCLabelAtlas::create("0", "figureLayer/number.png", 44, 40, '0');
        this->addChild(labelAtlas);
        labelAtlas->setPosition(ccp(400, 1200));
        
        hourLabelAtlas = CCLabelAtlas::create("02", "figureLayer/number.png", 44, 40, '0');
        this->addChild(hourLabelAtlas);
        hourLabelAtlas->setPosition(ccp(100, 1200));
        
        minLabelAtlas = CCLabelAtlas::create("59", "figureLayer/number.png", 44, 40, '0');
        this->addChild(minLabelAtlas);
        minLabelAtlas->setPosition(ccp(200, 1200));
        this->schedule(schedule_selector(GameLayer::minTimer),1,kCCRepeatForever,3);
        
        
        CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo(STATIC_DATA_STRING("level_png_" + *bigLevel), STATIC_DATA_STRING("level_plist_" + *bigLevel), STATIC_DATA_STRING("level_json_" + *bigLevel));
        armature = cocos2d::extension::CCArmature::create(STATIC_DATA_STRING("level_name_" + *bigLevel));
        armature->getAnimation()->playWithIndex(0);
        armature->setPosition(ccp(140,822));
        armature->setZOrder(8);
        this->addChild(armature);

        CCTexture2D *augerTexture = CCTextureCache::sharedTextureCache()->addImage(STATIC_DATA_STRING("auger_image"));
        _auger =(Auger*) Auger::spriteWithTexture(augerTexture);
        CC_BREAK_IF(!_auger);
        _auger->setAnchorPoint(ccp(0,0));
        _auger->setPosition(ccp(_auger->positionX,_auger->positionY));
        _auger->animateCount = 5;
        _auger->animateString = "toolLayer/yy_tool_1_96_109%d.png";
        this->addChild(_auger);
        
        CCTexture2D *brushTexture = CCTextureCache::sharedTextureCache()->addImage(STATIC_DATA_STRING("brush_image"));
        _brush = (Brush*) Brush::spriteWithTexture(brushTexture);
        CC_BREAK_IF(!_brush);
        _brush->setAnchorPoint(ccp(0,0));
        _brush->setPosition(ccp(_brush->positionX,_brush->positionY));
        _brush->animateCount = 2;
        _brush->animateString = "toolLayer/yy_tool_2_226_111%d.png";
        this->addChild(_brush);
        
        CCTexture2D *fixTexture = CCTextureCache::sharedTextureCache()->addImage(STATIC_DATA_STRING("fix_image"));
        _fix = (Fix*) Fix::spriteWithTexture(fixTexture);
        CC_BREAK_IF(!_fix);
        _fix->setAnchorPoint(ccp(0,0));
        _fix->setPosition(ccp(_fix->positionX,_fix->positionY));
        _fix->animateCount = 2;
        _fix->animateString = "toolLayer/yy_tool_3_349_108%d.png";
        this->addChild(_fix);
        
        CCTexture2D *hookTexture = CCTextureCache::sharedTextureCache()->addImage(STATIC_DATA_STRING("hook_image"));
        _hook = (Hook*) Hook::spriteWithTexture(hookTexture);
        CC_BREAK_IF(!_hook);
        _hook->setAnchorPoint(ccp(0,0));
        _hook->setPosition(ccp(_hook->positionX,_hook->positionY));
        _hook->animateCount = 1;
        _hook->animateString = "toolLayer/yy_tool_4_480_103%d.png";
        this->addChild(_hook);
        
        CCTexture2D *pliersTexture = CCTextureCache::sharedTextureCache()->addImage(STATIC_DATA_STRING("pliers_image"));
        _pliers = (Pliers*) Pliers::spriteWithTexture(pliersTexture);
        CC_BREAK_IF(!_fix);
        _pliers->setAnchorPoint(ccp(0,0));
        _pliers->setPosition(ccp(_pliers->positionX,_pliers->positionY));
        _pliers->animateCount = 1;
        _pliers->animateString = "toolLayer/yy_tool_5_596_110%d.png";
        this->addChild(_pliers);
        
        CCTexture2D *polishTexture = CCTextureCache::sharedTextureCache()->addImage(STATIC_DATA_STRING("polish_image"));
        _polish = (Polish*) Polish::spriteWithTexture(polishTexture);
        CC_BREAK_IF(!_polish);
        _polish->setAnchorPoint(ccp(0,0));
        _polish->setPosition(ccp(_polish->positionX,_polish->positionY));
        _polish->animateCount = 1;
        _polish->animateString = "toolLayer/yy_tool_6_724_111%d.png";
        this->addChild(_polish);
        
        CCTexture2D *oneToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/1/1_c_287_655.png");
        _oneTooth = (OneTooth*) OneTooth::spriteWithTexture(oneToothTexture);
        CC_BREAK_IF(!_oneTooth);
        _oneTooth->setPosition(ccp(287,1280 - 655));
        _oneTooth->setZOrder(5);
        this->addChild(_oneTooth);
        
        CCTexture2D *twoToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/2/2_c_331_665.png");
        _twoTooth = (TwoTooth*) TwoTooth::spriteWithTexture(twoToothTexture);
        CC_BREAK_IF(!_twoTooth);
        _twoTooth->setPosition(ccp(331,1280-665));
        _twoTooth->setZOrder(5);
        this->addChild(_twoTooth);
        
        CCTexture2D *threeToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/3/3_c_379_670.png");
        _threeTooth = (ThreeTooth*) ThreeTooth::spriteWithTexture(threeToothTexture);
        CC_BREAK_IF(!_threeTooth);
        _threeTooth->setPosition(ccp(379,1280-670));
        _threeTooth->setZOrder(5);
        this->addChild(_threeTooth);
        
        CCTexture2D *fourToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/4/4_c_428_665.png");
        _fourTooth = (FourTooth*) FourTooth::spriteWithTexture(fourToothTexture);
        CC_BREAK_IF(!_twoTooth);
        _fourTooth->setPosition(ccp(428,1280-665));
        _fourTooth->setZOrder(5);
        this->addChild(_fourTooth);
        
        CCTexture2D *fiveToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/5/5_c_474_653.png");
        _fiveTooth = (FiveTooth*) FiveTooth::spriteWithTexture(fiveToothTexture);
        CC_BREAK_IF(!_twoTooth);
        _fiveTooth->setPosition(ccp(474,1280-653));
        _twoTooth->setZOrder(5);
        this->addChild(_fiveTooth);
        
        CCTexture2D *sixToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/6/6_c_520_627.png");
        _sixTooth = (SixTooth*) SixTooth::spriteWithTexture(sixToothTexture);
        CC_BREAK_IF(!_sixTooth);
        _sixTooth->setPosition(ccp(520,1280-627));
        _sixTooth->setZOrder(5);
        this->addChild(_sixTooth);
        
        CCTexture2D *sevenToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/7/7_c_296_703.png");
        _sevenTooth = (SevenTooth*) SevenTooth::spriteWithTexture(sevenToothTexture);
        CC_BREAK_IF(!_sevenTooth);
        _sevenTooth->setPosition(ccp(296,1280-703));
        _sevenTooth->setZOrder(5);
        this->addChild(_sevenTooth);
        
        CCTexture2D *eightToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/8/8_c_337_717.png");
        _eightTooth = (EightTooth*) EightTooth::spriteWithTexture(eightToothTexture);
        CC_BREAK_IF(!_eightTooth);
        _eightTooth->setPosition(ccp(337,1280-717));
        _eightTooth->setZOrder(5);
        this->addChild(_eightTooth);
        
        CCTexture2D *nineToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/9/9_c_388_726.png");
        _nineTooth = (NineTooth*) NineTooth::spriteWithTexture(nineToothTexture);
        CC_BREAK_IF(!_nineTooth);
        _nineTooth->setPosition(ccp(388,1280-726));
        _nineTooth->setZOrder(5);
        this->addChild(_nineTooth);
        
        CCTexture2D *tenToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/10/10_c_438_722.png");
        _tenTooth = (TenTooth*) TenTooth::spriteWithTexture(tenToothTexture);
        CC_BREAK_IF(!_tenTooth);
        _tenTooth->setPosition(ccp(438,1280-722));
        _tenTooth->setZOrder(5);
        this->addChild(_tenTooth);
        
        CCTexture2D *elevenToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/11/11_c_486_707.png");
        _elevenTooth = (ElevenTooth*) ElevenTooth::spriteWithTexture(elevenToothTexture);
        CC_BREAK_IF(!_elevenTooth);
        _elevenTooth->setPosition(ccp(486,1280-707));
        _elevenTooth->setZOrder(5);
        this->addChild(_elevenTooth);
        
        CCTexture2D *twelveToothTexture = CCTextureCache::sharedTextureCache()->addImage("toothLayer/12/12_c_527_689.png");
        _twelveTooth = (TwelveTooth*) TwelveTooth::spriteWithTexture(twelveToothTexture);
        CC_BREAK_IF(!_twelveTooth);
        _twelveTooth->setPosition(ccp(527,1280-689));
        _twelveTooth->setZOrder(5);
        this->addChild(_twelveTooth);
        
        _augerTooth = new CCArray();
        _augerTooth->retain();
        _brushTooth = new CCArray();
        _brushTooth->retain();
        _fixTooth = new CCArray();
        _fixTooth->retain();
        _hookTooth = new CCArray();
        _hookTooth->retain();
        _pliersTooth = new CCArray();
        _pliersTooth->retain();
        _polishTooth = new CCArray();
        _polishTooth->retain();
        
        srand(time(NULL));
        badToothA = gen(12,5);
        badToothB = gen(12,5);
        
        checkSet = false;
        for_each(badToothA.begin(), badToothA.end(), bind1st(mem_fun(&GameLayer::addBadTooth), this));
        
        checkSet = true;
        for_each(badToothB.begin(), badToothB.end(), bind1st(mem_fun(&GameLayer::addBadTooth), this));

        for(std::set<std::string>::const_iterator it=badToothC.begin(); it!=badToothC.end(); ++it){
            std::string s = *it;
            int x = STATIC_DATA_INT(*it + "_x");
            int y = 1280 - STATIC_DATA_INT(*it + "_y");
            CCSprite* bt = CCSprite::create(STATIC_DATA_STRING(*it + "_image"));
            bt->setPosition(ccp(x, y));
            bt->setZOrder(6);
            this->addChild(bt);
            
            if(s.find("a")!= s.npos){
                fixNum +=10;
                _hookTooth -> addObject(bt);
            }else if(s.find("b")!= s.npos){
                fixNum +=10;
                _fixTooth -> addObject(bt);
            }else if(s.find("c")!= s.npos){
                fixNum +=10;
                _pliersTooth -> addObject(bt);
            }else if(s.find("d")!= s.npos){
                fixNum +=2;
                if (s.find("1")!=s.npos && s.length()==2) {
                    _oneTooth->setOpacity(5);
                    _polishTooth->addObject(_oneTooth);
                }
                if (s.find("2")!=s.npos && s.length()==2) {
                    _twoTooth->setOpacity(5);
                    _polishTooth->addObject(_twoTooth);
                }
                if (s.find("3")!=s.npos) {
                    _threeTooth->setOpacity(5);
                    _polishTooth->addObject(_threeTooth);
                }
                if (s.find("4")!=s.npos) {
                    _fourTooth->setOpacity(5);
                    _polishTooth->addObject(_fourTooth);
                }
                if (s.find("5")!=s.npos) {
                    _fiveTooth->setOpacity(5);
                    _polishTooth->addObject(_fiveTooth);
                }
                if (s.find("6")!=s.npos) {
                    _sixTooth->setOpacity(5);
                    _polishTooth->addObject(_sixTooth);
                }
                if (s.find("7")!=s.npos) {
                    _sevenTooth->setOpacity(5);
                    _polishTooth->addObject(_sevenTooth);
                }
                if (s.find("8")!=s.npos) {
                    _eightTooth->setOpacity(5);
                    _polishTooth->addObject(_eightTooth);
                }
                if (s.find("9")!=s.npos) {
                    _nineTooth->setOpacity(5);
                    _polishTooth->addObject(_nineTooth);
                }
                if (s.find("10")!=s.npos) {
                    _tenTooth->setOpacity(5);
                    _polishTooth->addObject(_tenTooth);
                }
                if (s.find("11")!=s.npos) {
                    _elevenTooth->setOpacity(5);
                    _polishTooth->addObject(_elevenTooth);
                }
                if (s.find("12")!=s.npos) {
                    _twelveTooth->setOpacity(5);
                    _polishTooth->addObject(_twelveTooth);
                }
                _augerTooth -> addObject(bt);
            }else if(s.find("e")!= s.npos){
                fixNum +=10;
                _brushTooth -> addObject(bt);
            }
        }
        pRet = true;
        this->scheduleUpdate();
        
        resaultLayer = CCLayer::create();
        CCSprite *settingBg = CCSprite::create("settingLayer/setting_bg_400_614.png");
        settingBg->setPosition(ccp(400, 1280-200+1000));
        resaultLayer->addChild(settingBg);
        this->addChild(resaultLayer);

    } while (0);
    return pRet;
}

void GameLayer::update(float dt)
{
//    CCRect testRect = CCRect(_auger->px + _auger->getPosition().x+35, _auger->py + _auger->getPosition().y+45, 10, 10);
//    CCLayerColor* c_layer = CCLayerColor::create(ccc4(1,1,100,123));
//    c_layer->setContentSize(CCSize(testRect.getMaxX()- testRect.getMinX(),testRect.getMaxY()-testRect.getMinY()));
//    c_layer->setAnchorPoint(CCPointZero);
//    c_layer->setPosition(ccp(testRect.getMinX(),testRect.getMinY()));
//    c_layer->setZOrder(10);
//    this->addChild(c_layer);
    
    CCObject* at;
    if(_auger->moveType == 1){
        CCRect augerRect = CCRect(_auger->px + _auger->getPosition().x+35, _auger->py + _auger->getPosition().y+45, 10, 10);
        CCARRAY_FOREACH(_augerTooth, at)
        {
            objectTooth = (CCSprite*)at;
            if (augerRect.intersectsRect(objectTooth->boundingBox()))
            {
                op = objectTooth->getOpacity();
                if(op> 0){
                    objectTooth->setOpacity(0);
                    testnum += 100;
                    labelAtlas->setPosition(ccp(400, 1200));
                    char str[10] = {0};
                    sprintf(str, "%d", testnum);
                    labelAtlas->setString(str);
                    fixNum -= 1;
                }
            }
        }
    }else if(_brush->moveType == 1){
        CCRect brushRect = CCRect(_brush->px + _brush->getPosition().x+8, _brush->py + _brush->getPosition().y-15, 38, 38);
        CCARRAY_FOREACH(_brushTooth, at)
        {
            objectTooth = (CCSprite*)at;
            if (brushRect.intersectsRect(objectTooth->boundingBox()))
            {
                op = objectTooth->getOpacity();
                if(op > 5){
                    op -= fixSpeed;
                    objectTooth->setOpacity(op);
                    testnum += 10;
                    labelAtlas->setPosition(ccp(400, 1200));
                    char str[10] = {0};
                    sprintf(str, "%d", testnum);
                    labelAtlas->setString(str);
                    fixNum -= 1;
                }
            }
        }
    }else if(_fix->moveType == 1){
        CCRect fixRect = CCRect(_fix->px + _fix->getPosition().x, _fix->py + _fix->getPosition().y-10, 10, 10);
        CCARRAY_FOREACH(_fixTooth, at)
        {
            objectTooth = (CCSprite*)at;
            if (fixRect.intersectsRect(objectTooth->boundingBox()))
            {
                op = objectTooth->getOpacity();
                if(op > 5){
                    op -= fixSpeed;
                    objectTooth->setOpacity(op);
                    testnum += 10;
                    labelAtlas->setPosition(ccp(400, 1200));
                    char str[10] = {0};
                    sprintf(str, "%d", testnum);
                    labelAtlas->setString(str);
                    fixNum -= 1;
                }
            }
        }
    }else if(_hook->moveType == 1){
        CCRect hookRect = CCRect(_hook->px + _hook->getPosition().x, _hook->py + _hook->getPosition().y, 12, 12);
        CCARRAY_FOREACH(_hookTooth, at)
        {
            objectTooth = (CCSprite*)at;
            if (hookRect.intersectsRect(objectTooth->boundingBox()))
            {
                op = objectTooth->getOpacity();
                if(op > 5){
                    op -= fixSpeed;
                    objectTooth->setOpacity(op);
                    testnum += 10;
                    labelAtlas->setPosition(ccp(400, 1200));
                    char str[10] = {0};
                    sprintf(str, "%d", testnum);
                    labelAtlas->setString(str);
                    fixNum -= 1;
                }
            }
        }
    }else if(_pliers->moveType == 1){
        CCRect pliersRect = CCRect(_pliers->px + _pliers->getPosition().x, _pliers->py + _pliers->getPosition().y, 38, 40);
        CCARRAY_FOREACH(_pliersTooth, at)
        {
            objectTooth = (CCSprite*)at;
            if (pliersRect.intersectsRect(objectTooth->boundingBox()))
            {
                op = objectTooth->getOpacity();
                if(op >5 ){
                    op -= fixSpeed;
                    objectTooth->setOpacity(op);
                    testnum += 10;
                    labelAtlas->setPosition(ccp(400, 1200));
                    char str[10] = {0};
                    sprintf(str, "%d", testnum);
                    labelAtlas->setString(str);
                    fixNum -= 1;
                }
            }
        }
    }else if(_polish->moveType == 1){
        CCRect polishRect = CCRect(_polish->px + _polish->getPosition().x, _polish->py + _polish->getPosition().y, 42, 25);
        CCARRAY_FOREACH(_polishTooth, at)
        {
            objectTooth = (CCSprite*)at;
            if (polishRect.intersectsRect(objectTooth->boundingBox()))
            {
                if(objectTooth->getOpacity()<=5){
                    objectTooth->setOpacity(255);
                    testnum += 10;
                    labelAtlas->setPosition(ccp(400, 1200));
                    char str[10] = {0};
                    sprintf(str, "%d", testnum);
                    labelAtlas->setString(str);
                    fixNum -= 1;
                }
            }
        }
    }
    CCLOG("asd %i",fixNum);
    if(fixNum==0){
        CCLOG("Win!!!!!!");
        this->unscheduleAllSelectors();
        resaultLayer->setZOrder(12);
        resaultLayer->runAction(CCEaseElasticIn::create(CCMoveBy::create(2, ccp(0, -1000))));
    }else{

    }
}

void GameLayer::minTimer(float dt){
    minStr = "";
    secStr = "";
    if(secs >= 0){
        if (secs<10) {
            secStr = "0" + std::to_string(secs);
        }else{
            secStr = std::to_string(secs);
        }
        minLabelAtlas->setString(secStr.c_str());
        if (secs == 0 && mins == 0){
            this->unschedule(schedule_selector(GameLayer::minTimer));
        }
    }else{
        secs = 59;
        minLabelAtlas->setString(std::to_string(secs).c_str());
        mins -= 1;
        if (mins<10) {
            minStr = "0" + std::to_string(mins);
        }else{
            minStr = std::to_string(mins);
        }
        hourLabelAtlas->setString(minStr.c_str());
    }
    secs -= 1;
}